<?php
/*
    Copyright (C) 2008 - 2010 Inanta Martsanto
    
    This file is part of Koma.

    Koma is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Koma is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Koma.  If not, see <http://www.gnu.org/licenses/>.
    
    Inanta Martsanto (inanta@inationsoft.com)
*/

abstract class KomaObject
{
    private $_properties = array();
    private $_readOnlyProperties = array();
    private $_writeOnlyProperties = array();
    
    function __get($property)
    {
        if(array_key_exists($property, $this->_properties))
        {
            if(!isset($this->_writeOnlyProperties[$property]))
            {
                return $this->_properties[$property];
            }
            
            throw new KomaPropertyException(array(
                                              'code' => WRITE_ONLY_PROPERTY,
                                              'property' => $property
                                              )
                                        );
        }
        
        throw new KomaPropertyException(array(
                                              'code' => UNDEFINED_GET,
                                              'property' => $property
                                              )
                                        );
    }
    
    function __set($property, $value)
    {
        if(array_key_exists($property, $this->_properties))
        {
            if(!isset($this->_readOnlyProperties[$property]))
            {
                $this->_properties[$property] = $value;
                return;
            }
            
            throw new KomaPropertyException(array(
                                              'code' => READ_ONLY_PROPERTY,
                                              'property' => $property,
                                              'value' => htmlentities($value)
                                              )
                                        );
        }
        else
        {
            throw new KomaPropertyException(array(
                                                  'code' => UNDEFINED_SET,
                                                  'property' => $property,
                                                  'value' => htmlentities($value)
                                              )
                                        );
        }
    }
    
    function __call($method, $arguments)
    {
        throw new KomaUndefinedMethodException($method, $arguments);
    }
    
    function __toString()
    {
        try
        {
            return $this->Name;
        }
        catch(Exception $e)
        {
            $this->initialize();
            return $this->Name;
        }
    }
    
    protected function initialize()
    {
        $this->createProperties(array('Name' => get_class($this)));
        $this->setReadOnlyProperties('Name');
    }
    
    function createProperties($properties)
    {
        if(!is_array($properties)) { $properties = array($properties => $properties); }
        
        foreach($properties as $property => $value)
        {
            $this->_properties[$property] = $value;
        }
    }
    
    function setReadOnlyProperties($properties)
    {
        if(!is_array($properties)) { $properties = array($properties => $properties); }
        
        foreach($properties as $property)
        {
            if(!isset($this->_properties[$property]))
            {
                throw new KomaPropertyException(array(
                                                      'code' => UNDEFINED_PROPERTY,
                                                      'property' => $property,
                                                  )
                                            );
            }
            else
            {
                if(isset($this->_writeOnlyProperties[$property]))
                {
                    throw new KomaPropertyException(array(
                                                      'code' => ALREADY_AS_WRITE_ONLY_PROPERTY,
                                                      'property' => $property,
                                                  )
                                            );
                }
                else
                {
                    $this->_readOnlyProperties[$property] = $property;
                }
            }
        }
    }
    
    function setWriteOnlyProperties($properties)
    {
        if(!is_array($properties)) { $properties = array($properties => $properties); }
        
        foreach($properties as $property)
        {
            if(!isset($this->_properties[$property]))
            {
                throw new KomaPropertyException(array(
                                                      'code' => UNDEFINED_PROPERTY,
                                                      'property' => $property,
                                                  )
                                            );
            }
            else
            {
                if(isset($this->_readOnlyProperties[$property]))
                {
                    throw new KomaPropertyException(array(
                                                      'code' => ALREADY_AS_READ_ONLY_PROPERTY,
                                                      'property' => $property,
                                                  )
                                            );
                }
                else
                {
                    $this->_writeOnlyProperties[$property] = $property;
                }
            }
        }
    }
}
?>